package com.wzdigit.wms.wms.service.transfer;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wzdigit.framework.Shift;
import com.wzdigit.wms.basic.client.Pager;
import com.wzdigit.wms.basic.client.PagerInfo;
import com.wzdigit.wms.basic.client.request.transfer.CommitTransferReq;
import com.wzdigit.wms.basic.client.request.transfer.SearchTransferTaskRequest;
import com.wzdigit.wms.basic.client.request.transfer.SingleStepTransferReq;
import com.wzdigit.wms.basic.client.response.Result;
import com.wzdigit.wms.basic.client.response.basic.LocationResponse;
import com.wzdigit.wms.basic.client.response.transfer.TransferDtlResp;
import com.wzdigit.wms.basic.client.response.transfer.TransferTaskDtlResponse;
import com.wzdigit.wms.basic.client.response.transfer.TransferTaskResponse;
import com.wzdigit.wms.basic.client.response.transfer.TransferTaskScanSnResponse;
import com.wzdigit.wms.basic.domain.basic.Sku;
import com.wzdigit.wms.basic.domain.basic.Warehouse;
import com.wzdigit.wms.basic.domain.dtos.inventory.UpdateInventoryInputDto;
import com.wzdigit.wms.basic.domain.inventory.Goods;
import com.wzdigit.wms.basic.domain.inventory.GoodsHis;
import com.wzdigit.wms.basic.domain.inventory.InvTrans;
import com.wzdigit.wms.basic.domain.inventory.Lotno;
import com.wzdigit.wms.basic.domain.mapping.CodeMapping;
import com.wzdigit.wms.basic.domain.mid.IfPostback;
import com.wzdigit.wms.basic.domain.transfer.*;
import com.wzdigit.wms.basic.enums.*;
import com.wzdigit.wms.basic.enums.operate.OperateCodeEnum;
import com.wzdigit.wms.basic.enums.writeback.BackResultEnum;
import com.wzdigit.wms.basic.enums.writeback.OtherSystemEnum;
import com.wzdigit.wms.basic.enums.writeback.TopicEnum;
import com.wzdigit.wms.basic.mapper.core.inventory.GoodsHisMapper;
import com.wzdigit.wms.basic.mapper.core.inventory.GoodsMapper;
import com.wzdigit.wms.basic.mapper.core.transfer.TransferDtlMapper;
import com.wzdigit.wms.basic.mapper.core.transfer.TransferHeaderMapper;
import com.wzdigit.wms.basic.service.code.InventoryService;
import com.wzdigit.wms.basic.service.code.LotnoService;
import com.wzdigit.wms.basic.util.StringUtils;
import com.wzdigit.wms.common.entity.CommonProperty;
import com.wzdigit.wms.common.entity.StatusCode;
import com.wzdigit.wms.basic.util.HttpSessionUtil;
import com.wzdigit.wms.common.utils.MyListUtil;
import com.wzdigit.wms.wms.client.web.service.common.wms2sap.ZDT_Reserve;
import com.wzdigit.wms.wms.client.web.service.wms2sap.transfer.ZDT_007_ReqRecordsHead;
import com.wzdigit.wms.wms.client.web.service.wms2sap.transfer.ZDT_007_ReqRecordsHeadItems;
import com.wzdigit.wms.wms.service.basic.LocationService;
import com.wzdigit.wms.wms.service.basic.SkuService;
import com.wzdigit.wms.wms.service.basic.WarehouseService;
import com.wzdigit.wms.wms.service.core.GoodsHisService;
import com.wzdigit.wms.wms.service.core.GoodsService;
import com.wzdigit.wms.wms.service.core.transfer.TransferDtlGoodsService;
import com.wzdigit.wms.wms.service.core.transfer.TransferDtlService;
import com.wzdigit.wms.wms.service.core.transfer.TransferHeaderService;
import com.wzdigit.wms.wms.service.mapping.CodeMappingNewService;
import com.wzdigit.wms.wms.service.mid.IfPostbackService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 调拨任务-pda
 *
 * @author Administrator
 */
@Service
@Slf4j
public class TransferTaskService {

    @Autowired
    private TransferHeaderMapper transferHeaderMapper;

    @Autowired
    private TransferDtlMapper transferDtlMapper;

    @Autowired
    private TransferDtlService transferDtlService;

    @Autowired
    private SkuService skuService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private GoodsHisMapper goodsHisMapper;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private TransferHeaderService transferHeaderService;

    @Autowired
    private WarehouseService warehouseService;

    @Autowired
    private TransferDtlGoodsService transferDtlGoodsService;

    @Autowired
    private InventoryService inventoryService;

    @Autowired
    private LotnoService lotnoService;

    @Autowired
    GoodsHisService goodsHisService;

    @Autowired
    @Lazy
    private IfPostbackService ifPostbackService;

    @Autowired
    private LocationService locationService;

    @Autowired
    private CodeMappingNewService codeMappingNewService;

    private final static Integer commonFlag = 1;

    //TODO ZYF:新加的
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Result backTranSap(Integer headerId, HttpServletRequest servletRequest){
        String loginName = HttpSessionUtil.getLoginName(servletRequest);
        TransferHeader header =
                transferHeaderMapper.selectOne(new QueryWrapper<TransferHeader>().eq("TRANSFER_HEADER_ID", headerId));
        if (header.getStatus().equals(TransferHeaderStatusEnum.CLOSE.code)){
            Shift.fatal("该调拨单已关闭!");
        }
        List<TransferDtl> dtlList = transferDtlMapper.
                selectList(new QueryWrapper<TransferDtl>().
                        eq("TRANSFER_HEADER_ID", headerId));
        List<TransferDtl> dtlFilterList = dtlList.stream().filter(t -> t.getCmpQty() > 0).collect(Collectors.toList());
        //至少一个明细关闭才能关闭调拨单
   /*     if (CollectionUtil.isEmpty(dtlFilterList)){
            Shift.fatal("请至少完成一次调拨任务!");
        }*/
        //回传SAP并把调拨单
        //报废调拨特殊处理

        //更新主档和明细状态为关闭
        Date nowDate=new Date();

        //生成出库单

        TransferHeader headerUpdate = new TransferHeader();

        headerUpdate.setTransferHeaderId(headerId);
        headerUpdate.setStatus(TransferHeaderStatusEnum.CLOSE.getCode());
        headerUpdate.setModifyTime(nowDate);
        headerUpdate.setModifyUser(loginName);
        headerUpdate.setCloseendTime(nowDate);
        //主档状态自动变为 关闭（5）
        headerUpdate = transferHeaderService.updateOne(headerUpdate);


        log.info(header.toString());

        //借还机和调拨都是写调SAP调拨接口
        //写入 接口中间表-数据回传
        //LXM说【完结】才写进去
        TransferHeader transferHeader = transferHeaderService.getByHeaderId(headerUpdate.getTransferHeaderId());
        IfPostback ifPostback = insertIfpostbackList(loginName, transferHeader, transferHeader.getTransferType());
        //新增到WMS_IF_POSTBACK
        ifPostbackService.addOne(ifPostback);

        transferDtlMapper.updateDtl(headerId,TransferDtlStatusEnum.CLOSE.code,loginName,nowDate );

//        Shift.fatal("///////////");

        return new  Result<>("关单成功!");
    }

    /**
     * 调拨任务列表
     * 
     * @param dto
     * @param pager
     * @return
     */
    public PagerInfo<List<TransferTaskResponse>> searchTransferTask(SearchTransferTaskRequest dto, Pager<?> pager) {
        Page<?> page = PageHelper.offsetPage(pager.getSkipCount(), pager.getMaxResultCount());
        PagerInfo<List<TransferTaskResponse>> pagerInfo = new PagerInfo<>();

        if (dto.getTransferDeptName() != null) {
            dto.setTransferDeptName(StringUtils.decode(dto.getTransferDeptName()));
        }
        List<TransferTaskResponse> list = transferHeaderMapper.getListTransferTask(dto,
                TransferManageService.transferTypeList, TransferManageService.transferStatusList);
        pagerInfo.setItems(list);
        pagerInfo.setTotalCount(page.getTotal());
        return pagerInfo;
    }

    /**
     * 调拨任务明细
     *
     * @param transferHeaderId
     * @return
     */
    public List<TransferTaskDtlResponse> searchTransferTaskDtl(Integer transferHeaderId) {
        List<TransferTaskDtlResponse> listTransferTaskDtl = transferDtlMapper.getListTransferTaskDtl(transferHeaderId);

        //根据行号排个序
        listTransferTaskDtl = listTransferTaskDtl.stream().sorted(Comparator.comparing(TransferTaskDtlResponse::getTransferLineNo)).collect(Collectors.toList());
        return listTransferTaskDtl;
    }

    /**
     * 获取调拨单明细
     *
     * @param transferDtlId
     * @param transferLineNo
     * @param servletRequest
     * @param servletResponse
     */
	public TransferDtlResp getTransferTaskDtl(Integer transferDtlId, String transferLineNo, String transferNo,
			HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
		TransferDtl transferDtl = transferDtlService.getTransferTaskDtlByPKAndLineNo(transferDtlId, transferLineNo, transferNo);
		if (transferDtl == null) {
			Shift.fatal(StatusCode.BUSINESS_ERR, "未查询到相关记录");
		}
		TransferDtlResp transferDtlResp = new TransferDtlResp();
		BeanUtils.copyProperties(transferDtl, transferDtlResp);

		// 设置物料编码
		Integer fmSku = transferDtlResp.getFmSku();
		if (fmSku == null) {
			Shift.fatal(StatusCode.BUSINESS_ERR, "单据明细不存在物料编码信息");
		}
		Sku sku = skuService.getSkuByPk(fmSku);
		transferDtlResp.setMaterialCode(sku.getSkuCode());
		// 设置客户机型
		transferDtlResp.setModel(sku.getModel());

		TransferHeader transferHeader = transferHeaderService.getByHeaderId(transferDtl.getTransferHeaderId());
		// 设置仓库
		Integer fmWhs = transferHeader.getFmWhs();
		if (fmWhs == null) {
			Shift.fatal(StatusCode.BUSINESS_ERR, "单据不存在转出仓信息");
		}
		transferDtlResp.setWhsId(fmWhs);
		Warehouse warehouse = warehouseService.selectByPK(fmWhs);
		if (warehouse == null) {
			Shift.fatal(StatusCode.BUSINESS_ERR, "未根据FM_WHS找到对应仓库，请核实单据信息");
		}

		String whsName = warehouse.getWhsName();
		transferDtlResp.setWarehouse(whsName);
		// 设置来源仓库
		transferDtlResp.setFmWhs(fmWhs);
		transferDtlResp.setFmWhsDesc(whsName);
		// 设置目标仓
		Integer toWhs = transferHeader.getToWhs();
		if (toWhs == null) {
			Shift.fatal(StatusCode.BUSINESS_ERR, "单据不存在转入仓信息");
		}
		Warehouse warehouseTarget = warehouseService.selectByPK(toWhs);
        if (warehouseTarget == null) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "单据不存在转入仓信息");
        }
		transferDtlResp.setToWhs(toWhs);
		transferDtlResp.setToWhsDesc(warehouseTarget.getWhsName());

		// 设置状态
		TransferDtlStatusEnum transferDtlStatusEnum = TransferDtlStatusEnum.getEnumByCode(transferDtlResp.getStatus());
		transferDtlResp.setStatusDesc(transferDtlStatusEnum.getEnumName());

		// 设置完成数
		if (Objects.equals(transferDtl.getCmpQty(), null)) {
			transferDtlResp.setCmpQty(0);
		}
		return transferDtlResp;
	}

    /**
     * 扫描SN
     *
     * @param sn
     * @param transferDtlId
     * @param servletRequest
     * @param servletResponse
     * @return
     */
    public Result<TransferTaskScanSnResponse> scanSn(String sn, Long transferDtlId, HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
        Goods goods = goodsService.selectBySn(sn);
        if (goods == null) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "未查询到该条码相关信息");
        }

        int waitUpCode = GoodsStatusEnum.WAIT_UP.getCode();//待上架
        int hasUpCode = GoodsStatusEnum.HAS_UP.getCode();//已上架
        int waitDowmCode = GoodsStatusEnum.WAIT_DOWM.getCode();//已上架 todo 后面加的

        if (!(goods.getStatus().equals(waitUpCode) || goods.getStatus().equals(hasUpCode) || goods.getStatus().equals(waitDowmCode))) {
            GoodsStatusEnum statusEnum = GoodsStatusEnum.getEnumByCode(goods.getStatus());

            String message = String.format("该条码的状态:【%s】不允许调拨", statusEnum.getEnumName());
            Shift.fatal(StatusCode.BUSINESS_ERR, message);
        }

        TransferDtl transferDtl = transferDtlService.getTransferTaskDtlByPK(transferDtlId);

        TransferHeader transferHeader = transferHeaderService.getByHeaderId(transferDtl.getTransferHeaderId());

        //校验码调拨单内容与SN信息是否一致
        checkSnEqualTransfer(goods, transferDtl, transferHeader);

        Sku sku = skuService.getSkuByPk(goods.getSkuId());
        if (sku == null) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "该条码未在货品主数据中维护");
        }

        TransferTaskScanSnResponse taskScanSnResponse = new TransferTaskScanSnResponse();
        taskScanSnResponse.setSn(goods.getGoodsSn());
        taskScanSnResponse.setPo(goods.getPoNo());
        taskScanSnResponse.setMaterialCode(sku.getSkuCode());
        taskScanSnResponse.setQty(goods.getQty());
        taskScanSnResponse.setModel(sku.getModel());

        Result<TransferTaskScanSnResponse> result = new Result<>();
        result.setData(taskScanSnResponse);
        return result;
    }

    /**
     * 调拨单信息(调拨单明细表)	SN信息(货品清单表)
     *
     * @param goods
     * @param transferDtl
     * @param transferHeader
     */
    private void checkSnEqualTransfer(Goods goods, TransferDtl transferDtl, TransferHeader transferHeader) {
        //调拨单信息(调拨单明细表)	SN信息(货品清单表)

        //调拨单类型
        String transferType = transferHeader.getTransferType();

        //来源货品	货品
        //仓库	仓库
        //来源货主	货主
        //来源工厂(组织)	工厂代码(组织)
        //来源供应商	供应商
        //来源库存性质	库存性质
        //来源货品品质状态	品质状态
        //来源订单号	采购订单
        //转出销售订单	销售订单
        //转出销售订单项目	销售订单行号
        //若字段数据一致，则校验通过，把产品SN返回，加入到【未提交SN】列表

        boolean flagSKu = Objects.equals(goods.getSkuId(), transferDtl.getFmSku());//货品
        if (!flagSKu) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "SN的货品与调拨单的不一致，录入失败");
        }
        boolean flagWhs = Objects.equals(goods.getWhsId(), transferHeader.getFmWhs());//仓库
        if (!flagWhs) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "SN的仓库与调拨单的不一致，录入失败");
        }
        boolean flagOwner = Objects.equals(goods.getOwner(), transferDtl.getFmOwner());//货主
        if (!flagOwner) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "SN的货主与调拨单的不一致，录入失败");
        }
        boolean flagFactory = Objects.equals(goods.getFactory(), transferDtl.getFmFactory());//工厂代码(组织)
        if (!flagFactory) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "SN的工厂代码（组织）与调拨单的不一致，录入失败");
        }
        boolean flagVendor = Objects.equals(goods.getVendorId(), transferDtl.getFmVendor());//供应商
        if (!flagVendor) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "SN的供应商与调拨单的不一致，录入失败");
        }
        boolean flagInvAttr = Objects.equals(goods.getInvAttr(), transferDtl.getFmInvAttr());//库存性质
        if (!flagInvAttr) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "SN的库存性质与调拨单的不一致，录入失败");
        }
        boolean flagQaStatus = Objects.equals(goods.getQaStatus(), transferDtl.getFmQaStatus());//品质状态

        //借还机不校验QAstatus
        if ((!transferType.equals(TransferTypeEnum.T06.getCode())) && (!transferType.equals(TransferTypeEnum.T05.getCode()))) {
            if (!flagQaStatus) {
                Shift.fatal(StatusCode.BUSINESS_ERR, "SN的品质状态与调拨单的不一致，录入失败");
            }
        }

        if (transferDtl.getFmLotno() != null) {
            boolean flagLotno = Objects.equals(goods.getLotno(), transferDtl.getFmLotno());//批次号
            if (!flagLotno) {
                Shift.fatal(StatusCode.BUSINESS_ERR, "SN的批次号与调拨单的不一致，录入失败");
            }

        } else {
            //批次号为NULL则验证字段
            boolean flagSo = Objects.equals(goods.getSoNo(), transferDtl.getFmSoNo());//销售订单
            if (!flagSo) {
                Shift.fatal(StatusCode.BUSINESS_ERR, "SN的销售订单与调拨单的不一致，录入失败");
            }
            boolean flagSoItem = Objects.equals(goods.getSoItem(), transferDtl.getFmSoLineNo());//销售订单行号
            if (!flagSoItem) {
                Shift.fatal(StatusCode.BUSINESS_ERR, "SN的销售订单行号与调拨单的不一致，录入失败");
            }
        }
    }


    /**
     * 获取已经扫描的记录
     * 查询 调拨单明细 对应的 调拨明细货品清单(WMS_TRANSFER_DTL_GOODS)
     *
     * @param transferDtlId
     * @param servletRequest
     * @param servletResponse
     * @return
     */
    public Result<List<TransferTaskScanSnResponse>> getCommitedSncanSn(Long transferDtlId, HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
        Result<List<TransferTaskScanSnResponse>> result = new Result<>();

        //清单集合，
        List<TransferDtlGoods> transferDtlGoodsList = transferDtlGoodsService.selectByDtlId(transferDtlId);
        if (transferDtlGoodsList.size() == 0) {
            return result;
        }

        List<TransferTaskScanSnResponse> transferTaskScanSnResponseList = new ArrayList<>();

        for (TransferDtlGoods transferDtlGoods : transferDtlGoodsList) {
            TransferTaskScanSnResponse transferTaskScanSnResponse = new TransferTaskScanSnResponse();
            transferTaskScanSnResponse.setSn(transferDtlGoods.getGoodsSn());
            transferTaskScanSnResponse.setQty(transferDtlGoods.getQty());
            transferTaskScanSnResponseList.add(transferTaskScanSnResponse);
        }



        List<String> snList = transferDtlGoodsList.stream().map(s -> s.getGoodsSn()).collect(Collectors.toList());

        List<Goods> goodsList = new ArrayList<>();
        if (snList.size() > 999) {
            List<List<String>> splitList = MyListUtil.splitList(snList, 999);

            for (List<String> split : splitList) {
                List<Goods> goodsSplitList = goodsService.selectListByListSn(split);
                goodsList.addAll(goodsSplitList);
                //查询历史表
                List<Goods> hisList = goodsHisService.selectListByListSn(snList);//查询历史表
                goodsList.addAll(hisList);

            }

        } else {
            goodsList = goodsService.selectListByListSn(snList);//查询goods
            List<Goods> hisList=  goodsHisService.selectListByListSn(snList);//查询历史表
            goodsList.addAll(hisList);

        }
        for (TransferTaskScanSnResponse transferTaskScanSnResponse : transferTaskScanSnResponseList) {
            for (Goods goods : goodsList) {
                if (goods.getGoodsSn().equals(transferTaskScanSnResponse.getSn())) {
                    transferTaskScanSnResponse.setPo(goods.getPoNo());//设置订单号
                    transferTaskScanSnResponse.setSkuId(goods.getSkuId());//设置SKU_ID
                    continue;
                }
            }
        }

        List<Integer> skuIdList = transferTaskScanSnResponseList.stream().filter(s -> s.getSkuId() != null).map(s -> s.getSkuId()).distinct().collect(Collectors.toList());
        List<Sku> skuList = new ArrayList<>();
        if(skuIdList!=null && skuIdList.size()>0) {//防止找不到条码报错
            skuList = skuService.getSkuListBySkuIdList(skuIdList);
        }

        for (TransferTaskScanSnResponse transferTaskScanSnResponse : transferTaskScanSnResponseList) {
            for (Sku sku : skuList) {
                if (sku.getSkuId().equals(transferTaskScanSnResponse.getSkuId())) {
                    transferTaskScanSnResponse.setMaterialCode(sku.getSkuCode());//物料编码
                    transferTaskScanSnResponse.setModel(sku.getModel());//机型
                }
            }
        }

        result.setData(transferTaskScanSnResponseList);

        return result;
    }

    /**
     * 一键调拨
     *
     * @param singleStepTransferReq
     * @param servletRequest
     * @param servletResponse
     * @return
     */
    public Result<List<TransferTaskScanSnResponse>> singleStepTransfer(SingleStepTransferReq singleStepTransferReq, HttpServletRequest servletRequest, HttpServletResponse servletResponse) {

        Result<List<TransferTaskScanSnResponse>> result = new Result<>();

        TransferDtl transferDtl = transferDtlService.getTransferTaskDtlByPK(singleStepTransferReq.getTransferDtlId());

        int waitUpCode = GoodsStatusEnum.WAIT_UP.getCode();
        int hasUpCode = GoodsStatusEnum.HAS_UP.getCode();
        int waitDowmCode = GoodsStatusEnum.WAIT_DOWM.getCode();

        singleStepTransferReq.setQaStatus(transferDtl.getFmQaStatus());
        singleStepTransferReq.setVendorId(transferDtl.getFmVendor());

        List<Integer> allowStatusList = Arrays.asList(waitUpCode, hasUpCode, waitDowmCode);

        List<TransferTaskScanSnResponse> taskScanSnResponseList = goodsService.getOnConditionSingleStepTransfer(singleStepTransferReq, allowStatusList);

        if (taskScanSnResponseList.size() == 0) {
            return result;
        }

        //查询出来的goods总数

        //查询出来的可用库存总数
        UpdateInventoryInputDto inputDto = new UpdateInventoryInputDto();
        inputDto.setWhsId(singleStepTransferReq.getWhsId());
        inputDto.setOwner(transferDtl.getFmOwner());
        inputDto.setSkuId(transferDtl.getFmSku());
        inputDto.setFactory(transferDtl.getFmFactory());
        inputDto.setVendorId(transferDtl.getFmVendor());

        inputDto.setLotNo(transferDtl.getFmLotno());
        inputDto.setInvAttr(transferDtl.getFmInvAttr());
        inputDto.setQaStatus(transferDtl.getFmQaStatus());

        BigDecimal stockCount = inventoryService.getSingleStepTransferInvQty(inputDto);

        Integer cmpQty = transferDtl.getCmpQty();
        if (cmpQty == null) {
            cmpQty = new Integer(0);
        }
        Integer orderQty = transferDtl.getOrderQty();
        if (orderQty == null) {
            orderQty = new Integer(0);
        }

        //需求数(调拨数-完成数）
        BigDecimal unfinishedCount = new BigDecimal(orderQty - cmpQty);

        if (unfinishedCount.compareTo(stockCount) == -1) {
            String message = String.format("校验1：当前仓库可用库存[%s]大于调拨需求数[%s]，无法一键调拨，请通过扫码完成调拨操作", stockCount, unfinishedCount);
            Shift.fatal(StatusCode.BUSINESS_ERR, message);
        }

        //当前仓库可用库存[XXX]大于调拨需求数[XXX]，无法一键调拨，请通过扫码完成调拨操作
        int size = taskScanSnResponseList.size();

        if (unfinishedCount.intValue() < size) {
            String message = String.format("校验2：当前符合条件的SN数量[%s]大于调拨需求数[%s]，无法一键调拨，请通过扫码完成调拨操作", size, unfinishedCount);
            Shift.fatal(StatusCode.BUSINESS_ERR, message);
        }
        result.setData(taskScanSnResponseList);
        return result;
    }

    /**
     * 提交调拨单
     *
     * @param dto
     * @param servletRequest
     * @param servletResponse
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Result<Integer> commitTransfer(CommitTransferReq dto, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception {
        Result<Integer> result = new Result<>();

        //调拨单明细
        Long transferDtlId = dto.getTransferDtlId();
        TransferDtl transferDtl = transferDtlService.getTransferTaskDtlByPK(transferDtlId);

        if (transferDtl.getStatus().equals(TransferDtlStatusEnum.CLOSE.getCode())) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "关闭的单据不能重复提交");
        }

        String loginName = HttpSessionUtil.getLoginName(servletRequest);
        Date nowDate = new Date();

        //待上架
        int waitUpCode = GoodsStatusEnum.WAIT_UP.getCode();
        //已上架
        int hasUpCode = GoodsStatusEnum.HAS_UP.getCode();
        //已下架
        int waitDowmCode = GoodsStatusEnum.WAIT_DOWM.getCode();


        List<String> snList = dto.getSnList();

        List<Goods> goodsList = new ArrayList<>();
        if (snList.size() > 999) {
            List<List<String>> splitList = MyListUtil.splitList(snList, 999);
            for (List<String> split : splitList) {
                List<Goods> goodsSplitList = goodsService.selectListByListSn(split);
                goodsList.addAll(goodsSplitList);
            }
        } else {
            goodsList = goodsService.selectListByListSn(snList);
        }

        if (goodsList.size() == 0) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "提交的SN数量为0");
        }

        Integer allowCount = Math.toIntExact(goodsList.stream().map(s -> s.getStatus())
                .filter(s -> Objects.equals(s, waitUpCode) || Objects.equals(s, hasUpCode)|| Objects.equals(s, waitDowmCode))
                .count());

        if (!allowCount.equals(goodsList.size())) {
            Shift.fatal(StatusCode.BUSINESS_ERR, "录入的条码存在非【待上架】、【已上架】、【已下架】状态的记录");
        }

        //查询是否有TO_LOTNO,无则调DJ服务生成新的批次号
        if (transferDtl.getToLotno() == null) {
            Lotno lotno = lotnoService.getLotnoByTransferDtlId(transferDtl.getTransferDtlId(), commonFlag);

            TransferDtl transferDtlUpdate = new TransferDtl();
            transferDtlUpdate.setToLotno(lotno.getLotno());
            transferDtlUpdate.setTransferDtlId(transferDtlId);

            transferDtlUpdate.setModifyTime(nowDate);
            transferDtlUpdate.setModifyUser(loginName);

            transferDtlService.updateOne(transferDtlUpdate);
            //更新后重新赋值
            transferDtl = transferDtlService.getTransferTaskDtlByPK(transferDtlId);
        }

        if (transferDtl.getCmpQty()>transferDtl.getOrderQty()){
            Shift.fatal("调拨数不能大于需求数!");
        }


        //调拨单单头
        TransferHeader transferHeader = transferHeaderService.getByHeaderId(transferDtl.getTransferHeaderId());

        if (transferHeader.getStatus().equals(TransferDtlStatusEnum.CREATE.getCode())) {

            log.info("调拨单头的状态是:【新建】，更新为【进行中】");
            TransferHeader transferHeaderUpdate = new TransferHeader();

            transferHeaderUpdate.setStatus(TransferDtlStatusEnum.DOING.getCode());
            transferHeaderUpdate.setTransferHeaderId(transferHeader.getTransferHeaderId());
            transferHeaderUpdate.setModifyUser(loginName);
            transferHeaderUpdate.setModifyTime(nowDate);

            transferHeaderService.updateOne(transferHeaderUpdate);
        }

        //货品主键集合
        List<Integer> goodsIdList = goodsList.stream().map(s -> s.getGoodsId()).collect(Collectors.toList());

        //根据单据类型判断走哪个分支
        String transferType = dto.getTransferType();

        if (transferType.equals(TransferTypeEnum.T03.getCode())) {
            // 库类调拨，组织间调拨
            organizationUpdateRepertory(loginName, nowDate, goodsList, transferDtl, goodsIdList, transferType);

        } else if (transferType.equals(TransferTypeEnum.T04.getCode())) {
            // 库类调拨，销售订单调拨
            // 单据类型：销售订单调拨(T04)
            // 更新货品清单(WMS_GOODS)的销售订单(SO_NO) 、销售订单行号(SO_ITEM)= 调拨单明细(WMS_TRANSFER_DTL)的目标销售订单号( TO_SO_NO)、目标销售订单行号(TO_SO_LINE_NO)。
            soUpdateRepertory(loginName, nowDate, goodsList, transferDtl, goodsIdList, transferType);

        } else if (transferType.equals(TransferTypeEnum.T05.getCode()) || transferType.equals(TransferTypeEnum.T06.getCode())) {
            // 借机、还机
            // 根据调拨单明细ID，获取调拨单明细行的信息
            // 更新货品清单(WMS_GOODS)的 仓库(WHS_ID) =调拨单表头的目标仓库(TO_WHS)、存储库位(LOC_ID)置空、货品状态(STATUS)=待上架(2)。
            jhUpdateRepertory(loginName, nowDate, waitUpCode, goodsList, transferDtl, transferHeader, goodsIdList, transferType);
        }

        /**
         * 提交的货品，写入调拨货品清单 表
         */
        for (Goods goods : goodsList) {
            TransferDtlGoods transferDtlGoods = new TransferDtlGoods();
            transferDtlGoods.setCreateUser(loginName);
            transferDtlGoods.setCreateTime(nowDate);
            transferDtlGoods.setGoodsId(goods.getGoodsId());
            transferDtlGoods.setGoodsSn(goods.getGoodsSn());

            transferDtlGoods.setQty(goods.getQty());
            transferDtlGoods.setTransferDtlId(transferDtlId);
            transferDtlGoods.setStatus(TransferDtlGoodStatusEnum.HAS_RECEIVE.getCode());
            transferDtlGoods.setQaStatus(goods.getQaStatus());

            transferDtlGoodsService.addNewOne(transferDtlGoods);
        }

        //更新完成数
        //5)更新调拨单明细行的状态为 关闭(5)
        TransferDtl transferDtlUpdate = new TransferDtl();

        BigDecimal countQty = goodsList.stream().filter(s -> s.getQty() != null).map(s -> s.getQty()).reduce(BigDecimal.ZERO, BigDecimal::add);

        transferDtlUpdate.setCmpQty(countQty.intValue());

        transferDtlUpdate.setTransferDtlId(transferDtlId).setStatus(TransferDtlStatusEnum.CLOSE.getCode());
        transferDtlUpdate.setModifyTime(nowDate);
        transferDtlUpdate.setModifyUser(loginName);

        transferDtlUpdate = transferDtlService.updateOne(transferDtlUpdate);


        //6)当调拨单明细行状态都变成 关闭(5) 时，主档状态自动变为 关闭（5）。同时弹出提示框，是否返回【调拨任务】页面
        List<TransferDtl> transferDtlList = transferDtlService.getByHeaderId(transferHeader.getTransferHeaderId());

        //明细已关闭的集合
        Integer closeCount = Math.toIntExact(transferDtlList.stream().map(s -> s.getStatus()).filter(s -> Objects.equals(s, TransferDtlStatusEnum.CLOSE.getCode())).count());


        if (TransferHeaderStatusEnum.CREATE.code.equals(transferHeader.getStatus())){
            TransferHeader header = new TransferHeader();
            header.setTransferHeaderId(transferHeader.getTransferHeaderId());
            header.setStatus(TransferHeaderStatusEnum.DOING.getCode());
            header.setModifyTime(nowDate);
            header.setModifyUser(loginName);
            header = transferHeaderService.updateOne(header);
        }
        /*if (closeCount.equals(transferDtlList.size())) {
            TransferHeader header = new TransferHeader();

            header.setTransferHeaderId(transferHeader.getTransferHeaderId());
            header.setStatus(TransferHeaderStatusEnum.CLOSE.getCode());
            header.setModifyTime(nowDate);
            header.setModifyUser(loginName);
            //主档状态自动变为 关闭（5）
            header = transferHeaderService.updateOne(header);

            log.info(header.toString());
            result.setData(CommonProperty.COMMON_TRUE);//设置返回标识

            //借还机和调拨都是写调SAP调拨接口
            //写入 接口中间表-数据回传
            //LXM说【完结】才写进去
            transferHeader = transferHeaderService.getByHeaderId(transferHeader.getTransferHeaderId());
            IfPostback ifPostback = insertIfpostbackList(loginName, transferHeader, transferType);
            //新增到WMS_IF_POSTBACK
            ifPostbackService.addOne(ifPostback);
        }*/
        //TODO 当调拨数量达到时系统自动点击关闭调拨的按钮
        if (closeCount.equals(transferDtlList.size())) {
            backTranSap(transferHeader.getTransferHeaderId(),servletRequest);
        }
        return result;
    }

    /**
     * 借机还机,更新库存
     *
     * @param loginName
     * @param nowDate
     * @param waitUpCode
     * @param goodsList
     * @param transferDtl
     * @param transferHeader
     * @param goodsIdList
     * @param transferType
     * @throws Exception
     */
    private void jhUpdateRepertory(String loginName, Date nowDate, int waitUpCode, List<Goods> goodsList, TransferDtl transferDtl, TransferHeader transferHeader, List<Integer> goodsIdList, String transferType) throws Exception {
        for (Goods goods : goodsList) {
            Goods goodsUpdate = new Goods();

            //存储库位(LOC_ID)置空,PKG_ID置空
            goodsUpdate.setWhsId(transferHeader.getToWhs());//仓库(WHS_ID) =调拨单表头的目标仓库(TO_WHS)
            goodsUpdate.setLocId(null);
            goodsUpdate.setPkgId(null);
            goodsUpdate.setStatus(waitUpCode);

            Integer updateRow = updateGoodsByGoodsId(loginName, nowDate, goods.getGoodsId(), goodsUpdate);


            //TODO 调库存更新服务，更新库位库存、库区库存。源仓库库存减少、目的仓库库存增加
            UpdateInventoryInputDto fmInv = new UpdateInventoryInputDto();
            //fmInv.setLocId(goods.getLocId());
            fmInv.setLocId(goods.getLocId());
            fmInv.setWhsId(goods.getWhsId());
            fmInv.setSkuId(goods.getSkuId());

            fmInv.setQty(goods.getQty().multiply(new BigDecimal(-1)));//库存数量
            fmInv.setOperator(loginName);

            fmInv.setUnit(transferDtl.getUnit());
            fmInv.setOwner(transferDtl.getFmOwner());
            fmInv.setFactory(transferDtl.getFmFactory());
            fmInv.setVendorId(transferDtl.getFmVendor());
            fmInv.setLotNo(transferDtl.getFmLotno());
            fmInv.setInvAttr(transferDtl.getFmInvAttr());
            fmInv.setQaStatus(goods.getQaStatus());


            UpdateInventoryInputDto toInv = new UpdateInventoryInputDto();
            toInv.setLocId(goodsUpdate.getLocId());
            toInv.setWhsId(goodsUpdate.getWhsId());

            toInv.setSkuId(goods.getSkuId());

            toInv.setQty(goods.getQty());
            toInv.setOperator(loginName);

            toInv.setUnit(transferDtl.getUnit());
            toInv.setOwner(transferDtl.getToOwner());
            toInv.setFactory(transferDtl.getToFactory());
            toInv.setVendorId(transferDtl.getToVendor());
            toInv.setLotNo(transferDtl.getToLotno());
            toInv.setInvAttr(transferDtl.getToInvAttr());
            toInv.setQaStatus(goods.getQaStatus());

            if (goods.getLocId() != null) {
                LocationResponse location = locationService.getLocation(goods.getLocId());
                fmInv.setZoneId(location.getZoneId());
//                toInv.setZoneId(location.getZoneId());
            }


            InvTrans invTrans = new InvTrans();
            invTrans.setCreateTime(nowDate);
            invTrans.setCreateUser(loginName);

            //todo 下面的数据很有问题
            invTrans.setOpCode(OperateCodeEnum.CREATE.getEnumName());//TODO 操作
            invTrans.setDocType(transferType);//单据类型
            invTrans.setDocNo(transferDtl.getTransferNo());//TODO 单据号==调拨单号？？
            invTrans.setStatus(InvTransStatusEnum.FINISHED.getCode()); //TODO 0 未完成，暂时写死 交易状态
            invTrans.setTransTime(nowDate);//TODO 交易时间
            invTrans.setOperator(loginName);
            invTrans.setFmOwner(fmInv.getOwner());//TODO 货主
            invTrans.setFmSkuId(fmInv.getSkuId());
//        sourceInvTrans.setFmLocId(source.getLocId());
            invTrans.setToWhsId(fmInv.getWhsId());
            invTrans.setFmUnit(fmInv.getUnit());
            invTrans.setFmQty(fmInv.getQty());
            invTrans.setToOwner(fmInv.getOwner());
            invTrans.setToSkuId(fmInv.getSkuId());
            invTrans.setToWhsId(fmInv.getWhsId());
            invTrans.setToUnit(fmInv.getUnit());
            invTrans.setToQty(fmInv.getQty());

            invTrans.setDocLineNo(transferDtl.getTransferLineNo());//TODO 单据行号
            invTrans.setFmWhsId(fmInv.getWhsId());//TODO 库存地点

            inventoryService.inventoryTransfer(fmInv, toInv, invTrans);
            //TODO 调库存更新服务，更新库位库存、库区库存。源仓库库存减少、目的仓库库存增加
        }
    }

    /**
     * 根据goodsID更新
     *
     * @param loginName
     * @param nowDate
     * @param goodsId
     * @param goodsUpdate
     * @return
     */
    private Integer updateGoodsByGoodsId(String loginName, Date nowDate, Integer goodsId, Goods goodsUpdate) {

        //我已不知为啥这么写，但是写了就写了，不想改了。

        goodsUpdate.setModifyTime(nowDate);
        goodsUpdate.setModifyUser(loginName);
        goodsUpdate.setGoodsId(goodsId);

        Integer row = goodsService.updateGoodsNullByGoodsId(goodsUpdate);
        log.info("成功更新{}条记录", row);

        return row;
    }

    /**
     * 销售订单调拨(T04),更新库存
     *
     * @param loginName
     * @param nowDate
     * @param goodsList
     * @param transferDtl
     * @param goodsIdList
     * @param transferType
     * @throws Exception
     */
    private void soUpdateRepertory(String loginName, Date nowDate, List<Goods> goodsList, TransferDtl transferDtl, List<Integer> goodsIdList, String transferType) throws Exception {

        Goods goodsUpdate = new Goods();
        goodsUpdate.setSoNo(transferDtl.getToSoNo());
        goodsUpdate.setSoItem(transferDtl.getToSoLineNo());
        goodsUpdate.setLotno(transferDtl.getToLotno());
        Integer updateRow = updateGoodsByGoodsIdList(loginName, nowDate, goodsIdList, goodsUpdate);
        log.info("成功更新{}条记录", updateRow);

        //批量更新库存
        Map<String, List<Goods>> keyGoodsMap = goodsList.stream().collect(Collectors.groupingBy(s -> this.groupKey(s.getLocId())));

        for (Map.Entry<String, List<Goods>> entry : keyGoodsMap.entrySet()) {

            List<Goods> goodsMapList = entry.getValue();
            Goods goods = goodsMapList.get(0);

            //
            UpdateInventoryInputDto fmInv = new UpdateInventoryInputDto();
            fmInv.setLocId(goods.getLocId());
            fmInv.setWhsId(goods.getWhsId());
            fmInv.setSkuId(goods.getSkuId());

            BigDecimal fmQty = new BigDecimal(goodsMapList.size()).negate();
//            fmInv.setQty(goods.getQty().multiply(new BigDecimal(-1)));//库存数量
            fmInv.setQty(fmQty);//库存数量


            fmInv.setOperator(loginName);
            fmInv.setQaStatus(goods.getQaStatus());

            fmInv.setUnit(transferDtl.getUnit());
            fmInv.setOwner(transferDtl.getFmOwner());
            fmInv.setFactory(transferDtl.getFmFactory());
            fmInv.setVendorId(transferDtl.getFmVendor());
            fmInv.setLotNo(transferDtl.getFmLotno());
            fmInv.setInvAttr(transferDtl.getFmInvAttr());

            UpdateInventoryInputDto toInv = new UpdateInventoryInputDto();
            toInv.setLocId(goods.getLocId());
            toInv.setWhsId(goods.getWhsId());


            toInv.setSkuId(goods.getSkuId());

            BigDecimal toQty = new BigDecimal(goodsMapList.size());
//            toInv.setQty(goods.getQty());
            toInv.setQty(toQty);
            toInv.setOperator(loginName);

            toInv.setUnit(transferDtl.getUnit());
            toInv.setOwner(transferDtl.getToOwner());
            toInv.setFactory(transferDtl.getToFactory());
            toInv.setVendorId(transferDtl.getToVendor());
            toInv.setLotNo(transferDtl.getToLotno());
            toInv.setInvAttr(transferDtl.getToInvAttr());
            toInv.setQaStatus(goods.getQaStatus());

            InvTrans invTrans = new InvTrans();
            invTrans.setCreateTime(nowDate);
            invTrans.setCreateUser(loginName);

            if (goods.getLocId() != null) {
                LocationResponse location = locationService.getLocation(goods.getLocId());
                toInv.setZoneId(location.getZoneId());
                fmInv.setZoneId(location.getZoneId());
            }

            //todo 下面的数据很有问题
            invTrans.setOpCode(OperateCodeEnum.CREATE.getEnumName());//TODO 操作
            invTrans.setDocType(transferType);//单据类型
            invTrans.setDocNo(transferDtl.getTransferNo());//TODO 单据号==调拨单号？？
            invTrans.setStatus(InvTransStatusEnum.FINISHED.getCode()); //TODO 0 未完成，暂时写死 交易状态
            invTrans.setTransTime(nowDate);//TODO 交易时间
            invTrans.setOperator(loginName);
            invTrans.setFmOwner(fmInv.getOwner());//TODO 货主
            invTrans.setFmSkuId(fmInv.getSkuId());
//        sourceInvTrans.setFmLocId(source.getLocId());
            invTrans.setToWhsId(fmInv.getWhsId());
            invTrans.setFmUnit(fmInv.getUnit());
            invTrans.setFmQty(fmInv.getQty());
            invTrans.setToOwner(fmInv.getOwner());
            invTrans.setToSkuId(fmInv.getSkuId());
            invTrans.setToWhsId(fmInv.getWhsId());
            invTrans.setToUnit(fmInv.getUnit());
            invTrans.setToQty(fmInv.getQty());

            invTrans.setDocLineNo(transferDtl.getTransferLineNo());//TODO 单据行号
            invTrans.setFmWhsId(fmInv.getWhsId());//TODO 库存地点

            inventoryService.inventoryTransfer(fmInv, toInv, invTrans);
        }
    }

    public String groupKey(Integer locId){

        String gKey = (locId == null ? "null" : locId.toString());
        return gKey;
    }


    public String groupKey(Integer locId, Integer qaStatus) {

        String locIdStr = (locId == null ? "null" : locId.toString());
        String qaStatusStr = (qaStatus == null ? "null" : qaStatus.toString());
        return locIdStr + "#" + qaStatusStr;
    }

    /**
     * 组织间调拨,更新库存
     *
     * @param loginName
     * @param nowDate
     * @param goodsList
     * @param transferDtl
     * @param goodsIdList
     * @param transferType
     * @throws Exception
     */
    private void organizationUpdateRepertory(String loginName, Date nowDate, List<Goods> goodsList, TransferDtl transferDtl, List<Integer> goodsIdList, String transferType) throws Exception {
        //库类调拨，组织间调拨,更新库存

        //批量操作
        Goods goodsUpdate = new Goods();
        goodsUpdate.setFactory(transferDtl.getToFactory());

        //YC说组织间调拨，订单号，销售订单号，销售订单行号，批次号要改 -start
        goodsUpdate.setSoNo(transferDtl.getToSoNo());
        goodsUpdate.setSoItem(transferDtl.getToSoLineNo());
        goodsUpdate.setPoNo(transferDtl.getToPo());
        goodsUpdate.setLotno(transferDtl.getToLotno());
        //YC说组织间调拨，订单号，销售订单号，销售订单行号，批次号要改 -end


        Integer updateRow = updateGoodsByGoodsIdList(loginName, nowDate, goodsIdList, goodsUpdate);
        log.info("成功更新{}条记录", updateRow);
        //批量更新GOODS

        //批量更新库存
        Map<String, List<Goods>> keyGoodsMap = goodsList.stream().collect(Collectors.groupingBy(s -> this.groupKey(s.getLocId())));

        for (Map.Entry<String, List<Goods>> entry : keyGoodsMap.entrySet()) {
            List<Goods> goodsMapList = entry.getValue();
            Goods goods = goodsMapList.get(0);


            UpdateInventoryInputDto fmInv = new UpdateInventoryInputDto();
            fmInv.setLocId(goods.getLocId());//TODO goods.getLocId()

            fmInv.setWhsId(goods.getWhsId());
            fmInv.setSkuId(goods.getSkuId());

            fmInv.setOwner(transferDtl.getFmOwner());
            fmInv.setFactory(transferDtl.getFmFactory());
            fmInv.setVendorId(transferDtl.getFmVendor());
            fmInv.setLotNo(transferDtl.getFmLotno());
            fmInv.setInvAttr(transferDtl.getFmInvAttr());
            fmInv.setUnit(transferDtl.getUnit());


//            fmInv.setQty(goods.getQty().multiply(new BigDecimal(-1)));//库存数量
            BigDecimal fmQty = new BigDecimal(goodsMapList.size()).negate();
            fmInv.setQty(fmQty);//库存数量

            fmInv.setOperator(loginName);
            fmInv.setQaStatus(goods.getQaStatus());

            UpdateInventoryInputDto toInv = new UpdateInventoryInputDto();
            toInv.setLocId(goods.getLocId());
            toInv.setWhsId(goods.getWhsId());
            toInv.setSkuId(goods.getSkuId());

            toInv.setOwner(transferDtl.getToOwner());//TODO transferDtl.getToOwner()
            toInv.setFactory(transferDtl.getToFactory());//todo transferDtl.getToFactory()
            toInv.setVendorId(transferDtl.getToVendor());//todo transferDtl.getToVendor()
            toInv.setLotNo(transferDtl.getToLotno());//TODO transferDtl.getToLotno()
            toInv.setInvAttr(transferDtl.getToInvAttr());//todo transferDtl.getToInvAttr()
            toInv.setUnit(transferDtl.getUnit());

            toInv.setQty(goods.getQty());
            BigDecimal toQty = new BigDecimal(goodsMapList.size());
            toInv.setQty(toQty);

            toInv.setOperator(loginName);
            toInv.setQaStatus(goods.getQaStatus());

            if (goods.getLocId() != null) {
                LocationResponse location = locationService.getLocation(goods.getLocId());
                toInv.setZoneId(location.getZoneId());
                fmInv.setZoneId(location.getZoneId());//TODO ZONE_ID
            }

            InvTrans invTrans = new InvTrans();
            invTrans.setCreateTime(nowDate);
            invTrans.setCreateUser(loginName);

            //todo 下面的数据很有问题
            invTrans.setOpCode(OperateCodeEnum.CREATE.getEnumName());//TODO 操作
            invTrans.setDocType(transferType);//单据类型
            invTrans.setDocNo(transferDtl.getTransferNo());//TODO 单据号==调拨单号？？ ************* transferDtl.getTransferNo()
            invTrans.setStatus(InvTransStatusEnum.FINISHED.getCode()); //TODO 0 未完成，暂时写死 交易状态
            invTrans.setTransTime(nowDate);//TODO 交易时间
            invTrans.setOperator(loginName);
            invTrans.setFmOwner(fmInv.getOwner());//TODO 货主
            invTrans.setFmSkuId(fmInv.getSkuId());

            invTrans.setToWhsId(fmInv.getWhsId());
            invTrans.setFmUnit(fmInv.getUnit());
            invTrans.setFmQty(fmInv.getQty());
            invTrans.setToOwner(fmInv.getOwner());
            invTrans.setToSkuId(fmInv.getSkuId());
            invTrans.setToWhsId(fmInv.getWhsId());
            invTrans.setToUnit(fmInv.getUnit());
            invTrans.setToQty(fmInv.getQty());

            invTrans.setDocLineNo(transferDtl.getTransferLineNo());//TODO 单据行号   **************  transferDtl.getTransferLineNo()
            invTrans.setFmWhsId(fmInv.getWhsId());//TODO 库存地点

            inventoryService.inventoryTransfer(fmInv, toInv, invTrans);
        }
        //批量更新库存
    }

    /**
     * 写入回传数据中间表
     *
     * @param loginName
     * @param goodsList
     * @param transferDtl
     * @param transferHeader
     * @param transferType
     */
    @Deprecated
    private void insertIfpostback(String loginName, List<Goods> goodsList, TransferDtl transferDtl, TransferHeader transferHeader, String transferType) {
        IfPostback ifPostback = new IfPostback();
        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());
        ifPostback.setPostbackTopic(TopicEnum.TOPIC_SAP_TRANSFER.getEnumName());

        Integer fmWhs = transferHeader.getFmWhs();
        String fmFactory = transferDtl.getFmFactory();
        Integer fmQaStatus = transferDtl.getFmQaStatus();
        Warehouse fmWarehouse = warehouseService.selectByPK(fmWhs);
        //根据WMS的仓库CODE+factory找SAP的仓库CODE
        String fmWhsCode = fmWarehouse.getWhsCode();
        CodeMapping fmCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(fmFactory, fmWhsCode, fmQaStatus);
        if (fmCodeMapping == null) {
            String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", fmWhsCode, fmFactory);
            Shift.fatal(StatusCode.BUSINESS_ERR, message);
        }


        Integer toWhs = transferHeader.getToWhs();
        String toFactory = transferDtl.getToFactory();
        Integer toQaStatus = transferDtl.getToQaStatus();
        Warehouse toWarehouse = warehouseService.selectByPK(toWhs);
        //根据WMS的仓库CODE+factory找SAP的仓库CODE
        String toWhsCode = toWarehouse.getWhsCode();
        CodeMapping toCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(toFactory, toWhsCode, toQaStatus);
        if (toCodeMapping == null) {
            String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", toWhsCode, toFactory);
            Shift.fatal(StatusCode.BUSINESS_ERR, message);
        }


        ZDT_007_ReqRecordsHead head = new ZDT_007_ReqRecordsHead();

        if (transferType.equals(TransferTypeEnum.T03.getCode())) {
            //组织间调拨
            head.setZCJLX("2");//创建类型
            head.setBWART("");//移动类型（创建类型2无需填）

        } else if (transferType.equals(TransferTypeEnum.T04.getCode())) {
            //销售订单调拨
            head.setZCJLX("4");//创建类型

            String erpMoveType = transferHeader.getErpMoveType();
            if (erpMoveType == null) {
                erpMoveType = "";
                log.warn("ERP_MOVE_TYPE字段的值为NULL");
            }
            head.setBWART(erpMoveType);//移动类型（创建类型2无需填）

        } else if (transferType.equals(TransferTypeEnum.T05.getCode()) || transferType.equals(TransferTypeEnum.T06.getCode())) {
            //借机||还机
            head.setZCJLX("1");//创建类型
            head.setBWART("311");//移动类型（创建类型2 无需填）
        }


        head.setZGLJYD(transferDtl.getTransferNo());//调拨单号

        if (transferHeader.getPurchsingOrg() != null) {
            head.setEKORG(transferHeader.getPurchsingOrg());//采购组织（创建类型2必填）
        } else {
            head.setEKORG("");//采购组织（创建类型2必填）
        }

        if (transferHeader.getCompanyCode() != null) {
            head.setBUKRS(transferHeader.getCompanyCode());//公司代码（创建类型2必填）
        } else {
            head.setBUKRS("");//公司代码（创建类型2必填）
        }


        if (transferDtl.getFmVendor() != null) {
            head.setLIFNR(transferDtl.getFmVendor().toString());//供应商 （创建类型2必填）
        } else {
            head.setLIFNR("");//供应商 （创建类型2必填）
        }


        head.setZCJR(loginName);//创建人
        head.setZCJRZH(loginName);//创建人账号

        head.setZCJRQ(getDateStr());//创建日期
        head.setZCJSJ(getTimeStr());//创建时间


        ZDT_Reserve reserve = new ZDT_Reserve();

        reserve.setRsv1("");
        reserve.setRsv2("");
        reserve.setRsv3("");
        reserve.setRsv4("");
        reserve.setRsv5("");
        head.setRSV(reserve);

        //ITEMS

        List<ZDT_007_ReqRecordsHeadItems> items = new ArrayList<>();

        BigDecimal qty = goodsList.stream().filter(s -> s.getQty() != null).map(s -> s.getQty()).reduce(BigDecimal.ZERO, BigDecimal::add);

        Goods goods = goodsList.get(0);

//        for (Goods goods : goodsList) {
        ZDT_007_ReqRecordsHeadItems headItems = new ZDT_007_ReqRecordsHeadItems();
        // private String ZCGHH;
        //    private String SOBKZ;
        //    private String UMSOK;
        //    private String KDAUF;
        //    private String KDPOS;
        //    private String MAT_KDAUF;
        //    private String MAT_KDPOS;
        //    private String WERKS;
        //    private String UMLGO;
        //    private String UMWRK;
        //    private String LGORT;
        //    private String MATNR;
        //    private String MENGE;
        //    private String BUDAT;
        //    private ZDT_Reserve RSV;

        headItems.setZCGHH(transferDtl.getTransferLineNo());//调拨单行号

        //特殊库存 的意思 就是库存是绑定订单的,转出转入都绑定,所以是两个e from SAP——WZP
        headItems.setSOBKZ("E");//特殊库存标识（转出）
        headItems.setUMSOK("E");//特殊库存标识（转入）


        headItems.setKDAUF(transferDtl.getFmSoNo());//订单号码（转出）
        headItems.setKDPOS(transferDtl.getFmSoLineNo());//订单行项目（转出）

        headItems.setMAT_KDAUF(transferDtl.getToSoNo());//订单号码（转入）
        headItems.setMAT_KDPOS(transferDtl.getToSoLineNo());//订单行项目（转入）

        headItems.setWERKS(fmFactory);//工厂（转出）
        headItems.setUMLGO(fmCodeMapping.getMappingCode());//库位（转出）/SAP说传他们的仓库


        headItems.setUMWRK(toFactory);//工厂（转入）
        headItems.setLGORT(toCodeMapping.getMappingCode());//库位（转入）/SAP说传他们的仓库

        Sku sku = skuService.getSkuByPk(goods.getSkuId());
        headItems.setMATNR(sku.getSkuCode());//物料号

//            headItems.setMENGE(goods.getQty().toString());//数量
        headItems.setMENGE(qty.toString());//数量

        headItems.setBUDAT(getDateStr());//过帐日期

        ZDT_Reserve zdt_reserve = new ZDT_Reserve();
        zdt_reserve.setRsv1("");
        zdt_reserve.setRsv2("");
        zdt_reserve.setRsv3("");
        zdt_reserve.setRsv4("");
        zdt_reserve.setRsv5("");

        headItems.setRSV(zdt_reserve);

        items.add(headItems);
//        }


        ZDT_007_ReqRecordsHeadItems[] recordsHeadItemsArr = items.toArray(new ZDT_007_ReqRecordsHeadItems[items.size()]);

        head.setItems(recordsHeadItemsArr);

        List<ZDT_007_ReqRecordsHead> headArrays = new ArrayList<ZDT_007_ReqRecordsHead>();
        headArrays.add(head);

        String jsonString = JSON.toJSONString(headArrays);


        ifPostback.setPostbackContent(jsonString);
        ifPostback.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
        ifPostback.setCreateTime(new Date());
        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());

        ifPostbackService.addOne(ifPostback);
    }

    /**
     * 根据goods的主键集合更新
     *
     * @param loginName
     * @param nowDate
     * @param goodsIdList
     * @param goods
     */
	private Integer updateGoodsByGoodsIdList(String loginName, Date nowDate, List<Integer> goodsIdList, Goods goods) {
		goods.setModifyTime(nowDate);
		goods.setModifyUser(loginName);

		Integer updateRow = 0;
		if (goodsIdList.size() > 999) {
			List<List<Integer>> splitList = MyListUtil.splitList(goodsIdList, 999);
			for (List<Integer> split : splitList) {
				Integer row = goodsService.updateGoodsList(split, goods);
				updateRow += row;
			}
		} else {
			updateRow = goodsService.updateGoodsList(goodsIdList, goods);
		}
		return updateRow;
	}

    /**
     * 关单后写进来
     *
     * @param
     * @param transferHeader
     * @param transferType
     */
    public IfPostback insertIfpostbackList(String loginName, TransferHeader transferHeader, String transferType) {
        IfPostback ifPostback = new IfPostback();
        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());
        ifPostback.setPostbackTopic(TopicEnum.TOPIC_SAP_TRANSFER.getEnumName());
        ifPostback.setPostbackNo(transferHeader.getTransferNo());
        ifPostback.setPostbackType(transferType);
        ifPostback.setPostbackSourceNo(transferHeader.getSourceNo());


        List<TransferDtl> dtlList = transferDtlMapper.
                selectList(new QueryWrapper<TransferDtl>().
                        eq("TRANSFER_HEADER_ID", transferHeader.getTransferHeaderId()));
        List<TransferDtl> transferDtlList = dtlList.stream().filter(t -> t.getCmpQty() > 0).collect(Collectors.toList());

//        List<TransferDtl> transferDtlList = transferDtlService.getByHeaderId(transferHeader.getTransferHeaderId());
        //

        Integer fmWhs = transferHeader.getFmWhs();//单头源仓库
        Integer toWhs = transferHeader.getToWhs();//单头目的仓

        ZDT_007_ReqRecordsHead head = new ZDT_007_ReqRecordsHead();

        if (transferType.equals(TransferTypeEnum.T03.getCode())) {
            //组织间调拨
            head.setZCJLX("2");//创建类型
            head.setBWART("");//移动类型（创建类型2无需填）

        } else if (transferType.equals(TransferTypeEnum.T04.getCode())) {
            //销售订单调拨
            head.setZCJLX("4");//创建类型

            String erpMoveType = transferHeader.getErpMoveType();
            if (erpMoveType == null) {
                erpMoveType = "";
                log.warn("ERP_MOVE_TYPE字段的值为NULL");
            }
            head.setBWART(erpMoveType);//移动类型（创建类型2无需填）

        } else if (transferType.equals(TransferTypeEnum.T05.getCode()) || transferType.equals(TransferTypeEnum.T06.getCode())||transferType.equals(TransferTypeEnum.T01.getCode())) {
            //借机||还机
            head.setZCJLX("1");//创建类型
            head.setBWART("311");//移动类型（创建类型2 无需填）
        }

        head.setZGLJYD(transferHeader.getTransferNo());//调拨单号

        if (transferHeader.getPurchsingOrg() != null) {
            head.setEKORG(transferHeader.getPurchsingOrg());//采购组织（创建类型2必填）
        } else {
            head.setEKORG("");//采购组织（创建类型2必填）
        }

        if (transferHeader.getCompanyCode() != null) {
            head.setBUKRS(transferHeader.getCompanyCode());//公司代码（创建类型2必填）
        } else {
            head.setBUKRS("");//公司代码（创建类型2必填）
        }


        head.setZCJR(loginName);//创建人
        head.setZCJRZH(loginName);//创建人账号

        head.setZCJRQ(getDateStr());//创建日期
        head.setZCJSJ(getTimeStr());//创建时间


        ZDT_Reserve reserve = new ZDT_Reserve();

        reserve.setRsv1("");
        reserve.setRsv2("");
        reserve.setRsv3("");
        reserve.setRsv4("");
        reserve.setRsv5("");
        head.setRSV(reserve);


        List<ZDT_007_ReqRecordsHeadItems> items = new ArrayList<>();

        //设置ITEMS
        if(transferType.equals(TransferTypeEnum.T05.getCode()) || transferType.equals(TransferTypeEnum.T06.getCode())||transferType.equals(TransferTypeEnum.T01.getCode())){
            // 借机【T05】、还机【T06】
        	createT05AndT06Items(transferDtlList, fmWhs, toWhs, head, items,transferType);
        } else {
            createT03AndT04Items(transferDtlList, fmWhs, toWhs, head, items);
        }

        ZDT_007_ReqRecordsHeadItems[] recordsHeadItemsArr = items.toArray(new ZDT_007_ReqRecordsHeadItems[items.size()]);

        head.setItems(recordsHeadItemsArr);

        List<ZDT_007_ReqRecordsHead> headArrays = new ArrayList<ZDT_007_ReqRecordsHead>();
        headArrays.add(head);

        String jsonString = JSON.toJSONString(headArrays);


        ifPostback.setPostbackContent(jsonString);
        ifPostback.setPostbackResult(BackResultEnum.DEFAULT_STATE.getCode());
        ifPostback.setCreateTime(new Date());
        ifPostback.setCreateUser(loginName);
        ifPostback.setDestSystem(OtherSystemEnum.SYSYTEM_SAP.getEnumName());

        return ifPostback;
    }

    /**
     * 借机，还机调拨
     * @param transferDtlList
     * @param fmWhs
     * @param toWhs
     * @param head
     * @param items
     */
    private void createT05AndT06Items(List<TransferDtl> transferDtlList, Integer fmWhs, Integer toWhs, ZDT_007_ReqRecordsHead head, List<ZDT_007_ReqRecordsHeadItems> items,String transferType) {
        for (TransferDtl transferDtl : transferDtlList) {

            Long transferDtlId = transferDtl.getTransferDtlId();


            List<TransferDtlGoods> transferDtlGoodsList = transferDtlGoodsService.selectByDtlId(transferDtlId);
            //TODO ZYF新加的：还机那一刻取SN的实际品质状态
            if (transferType.equals(TransferTypeEnum.T06.getCode())){
                List<String> snList = transferDtlGoodsList.stream().map(t -> t.getGoodsSn()).collect(Collectors.toList());
                List<Goods> goodsList = goodsMapper.selectList(new QueryWrapper<Goods>().in("GOODS_SN", snList));
                Map<String, List<Goods>> goodsMap = goodsList.stream().collect(Collectors.groupingBy(Goods::getGoodsSn));
                for (TransferDtlGoods goods : transferDtlGoodsList) {
                    List<Goods> goodsUpdateList = goodsMap.get(goods.getGoodsSn());
                    if (!CollectionUtil.isEmpty(goodsUpdateList)){
                        goods.setQaStatus(goodsUpdateList.get(0).getQaStatus());
                    }
                }
            }

            //根据DTL_GOODS下面的QA_STATUS分组传，
            Map<Integer, List<TransferDtlGoods>> qaStatusMap = transferDtlGoodsList.stream().collect(Collectors.groupingBy(s -> s.getQaStatus()));

            for (Map.Entry<Integer, List<TransferDtlGoods>> entry : qaStatusMap.entrySet()) {

                Integer keyQa = entry.getKey();//WMS_TRANSFER_DTL_GOODS:QA_STATUS
                List<TransferDtlGoods> dtlGoodsList = entry.getValue();
                int qty = dtlGoodsList.size();

                String fmFactory = transferDtl.getFmFactory();
                Integer fmQaStatus = transferDtl.getFmQaStatus();

                Warehouse fmWarehouse = warehouseService.selectByPK(fmWhs);
                //根据WMS的仓库CODE+factory找SAP的仓库CODE
                String fmWhsCode = fmWarehouse.getWhsCode();
//                    CodeMapping fmCodeMapping = codeMappingService.selectByWhsCodeAndFactory(fmFactory, fmWhsCode, fmQaStatus);
                CodeMapping fmCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(fmFactory, fmWhsCode, keyQa);
                if (fmCodeMapping == null) {
                    String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", fmWhsCode, fmFactory);
                    Shift.fatal(StatusCode.BUSINESS_ERR, message);
                }


                String toFactory = transferDtl.getToFactory();
                Integer toQaStatus = transferDtl.getToQaStatus();
                Warehouse toWarehouse = warehouseService.selectByPK(toWhs);
                //根据WMS的仓库CODE+factory找SAP的仓库CODE
                String toWhsCode = toWarehouse.getWhsCode();
//                CodeMapping toCodeMapping = codeMappingService.selectByWhsCodeAndFactory(toFactory, toWhsCode, toQaStatus);
                CodeMapping toCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(toFactory, toWhsCode, keyQa);
                if (toCodeMapping == null) {
                    String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", toWhsCode, toFactory);
                    Shift.fatal(StatusCode.BUSINESS_ERR, message);
                }


                log.info("供应商：{}", transferDtl.getUdf5());
                if (transferDtl.getUdf5() != null) {
                    head.setLIFNR(transferDtl.getUdf5());//供应商 （创建类型2必填），YC说明细的FM供应商都是一样的,YC说改成取这个值
                } else {
                    head.setLIFNR("");//供应商 （创建类型2必填）
                }

                List<TransferDtlGoods> transferDtlGoods = transferDtlGoodsService.selectByDtlId(transferDtl.getTransferDtlId());

//                    BigDecimal qty = transferDtlGoods.stream().filter(s -> s.getQty() != null).map(s -> s.getQty()).reduce(BigDecimal.ZERO, BigDecimal::add);

                TransferDtlGoods dtlGoods = transferDtlGoods.get(0);
                Goods goods = goodsService.selectBySn(dtlGoods.getGoodsSn());


                if (goods==null){
                    List<String> hisGoodsSnList=new ArrayList<>();
                    hisGoodsSnList.add(dtlGoods.getGoodsSn());
                    List<Goods> goodshisList = goodsHisMapper.selectGoodsWithWhsByHisSn(hisGoodsSnList);
                    goods=goodshisList.get(0);
                }

                ZDT_007_ReqRecordsHeadItems headItems = new ZDT_007_ReqRecordsHeadItems();

                headItems.setZCGHH(transferDtl.getTransferLineNo());//调拨单行号

                //特殊库存 的意思 就是库存是绑定订单的,转出转入都绑定,所以是两个e from SAP——WZP
                headItems.setSOBKZ("E");//特殊库存标识（转出）
                headItems.setUMSOK("E");//特殊库存标识（转入）

                if (transferDtl.getToSoNo() == null) {
                    headItems.setKDAUF("");//订单号码（转出）
                } else {
                    headItems.setKDAUF(transferDtl.getToSoNo());//订单号码（转出）
                }

                headItems.setKDPOS(transferDtl.getFmSoLineNo());//订单行项目（转出）

                if (transferDtl.getFmSoNo() == null) {
                    headItems.setMAT_KDAUF("");//订单号码（转入）
                } else {
                    headItems.setMAT_KDAUF(transferDtl.getFmSoNo());//订单号码（转入）
                }
                headItems.setMAT_KDPOS(transferDtl.getToSoLineNo());//订单行项目（转入）

                headItems.setWERKS(fmFactory);//工厂（转出）
                headItems.setUMLGO(fmCodeMapping.getMappingCode());//库位（转出）/SAP说传他们的仓库


                headItems.setUMWRK(toFactory);//工厂（转入）
                headItems.setLGORT(toCodeMapping.getMappingCode());//库位（转入）/SAP说传他们的仓库

                Sku sku = skuService.getSkuByPk(goods.getSkuId());
                headItems.setMATNR(sku.getSkuCode());//物料号

//                    headItems.setMENGE(qty.toString());//数量
                headItems.setMENGE(String.valueOf(qty));//数量

                headItems.setBUDAT(getDateStr());//过帐日期

                ZDT_Reserve zdt_reserve = new ZDT_Reserve();
                zdt_reserve.setRsv1("");
                zdt_reserve.setRsv2("");
                zdt_reserve.setRsv3("");
                zdt_reserve.setRsv4("");
                zdt_reserve.setRsv5("");

                headItems.setRSV(zdt_reserve);

                items.add(headItems);
            }
        }
    }

    /**
     * 组织间调拨，销售订单调拨
     * @param transferDtlList
     * @param fmWhs
     * @param toWhs
     * @param head
     * @param items
     */
    private void createT03AndT04Items(List<TransferDtl> transferDtlList, Integer fmWhs, Integer toWhs, ZDT_007_ReqRecordsHead head, List<ZDT_007_ReqRecordsHeadItems> items) {
        for (TransferDtl transferDtl : transferDtlList) {
            String fmFactory = transferDtl.getFmFactory();
            Integer fmQaStatus = transferDtl.getFmQaStatus();
            Warehouse fmWarehouse = warehouseService.selectByPK(fmWhs);
            //根据WMS的仓库CODE+factory找SAP的仓库CODE
            String fmWhsCode = fmWarehouse.getWhsCode();
            CodeMapping fmCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(fmFactory, fmWhsCode, fmQaStatus);
            if (fmCodeMapping == null) {
                String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", fmWhsCode, fmFactory);
                Shift.fatal(StatusCode.BUSINESS_ERR, message);
            }


            String toFactory = transferDtl.getToFactory();
            Integer toQaStatus = transferDtl.getToQaStatus();
            Warehouse toWarehouse = warehouseService.selectByPK(toWhs);
            //根据WMS的仓库CODE+factory找SAP的仓库CODE
            String toWhsCode = toWarehouse.getWhsCode();
            CodeMapping toCodeMapping = codeMappingNewService.selectByWhsCodeAndFactory(toFactory, toWhsCode, toQaStatus);
            if (toCodeMapping == null) {
                String message = String.format("根据调拨单明细的仓库CODE:【%s】和工厂代码:【%s】未找SAP对应的仓库信息,请维护【内外部系统代码映射表】", toWhsCode, toFactory);
                Shift.fatal(StatusCode.BUSINESS_ERR, message);
            }


//            if (transferDtl.getFmVendor() != null) {
            log.info("供应商：{}", transferDtl.getUdf5());
            log.info("供应商：{}", transferDtl.getUdf5());
            log.info("供应商：{}", transferDtl.getUdf5());
            if (transferDtl.getUdf5() != null) {
//                head.setLIFNR(transferDtl.getFmVendor().toString());//供应商 （创建类型2必填），YC说明细的FM供应商都是一样的
                head.setLIFNR(transferDtl.getUdf5());//供应商 （创建类型2必填），YC说明细的FM供应商都是一样的,YC说改成取这个值
            } else {
                head.setLIFNR("");//供应商 （创建类型2必填）
            }

            List<TransferDtlGoods> transferDtlGoods = transferDtlGoodsService.selectByDtlId(transferDtl.getTransferDtlId());

            BigDecimal qty = transferDtlGoods.stream().filter(s -> s.getQty() != null).map(s -> s.getQty()).reduce(BigDecimal.ZERO, BigDecimal::add);

            TransferDtlGoods dtlGoods = transferDtlGoods.get(0);
            Goods goods = goodsService.selectBySn(dtlGoods.getGoodsSn());

            ZDT_007_ReqRecordsHeadItems headItems = new ZDT_007_ReqRecordsHeadItems();

            headItems.setZCGHH(transferDtl.getTransferLineNo());//调拨单行号

            //特殊库存 的意思 就是库存是绑定订单的,转出转入都绑定,所以是两个e from SAP——WZP
            headItems.setSOBKZ("E");//特殊库存标识（转出）
            headItems.setUMSOK("E");//特殊库存标识（转入）


//            headItems.setKDAUF(transferDtl.getFmSoNo());//订单号码（转出）
            if (transferDtl.getToSoNo() == null) {
                headItems.setKDAUF("");//订单号码（转出）
            } else {
                headItems.setKDAUF(transferDtl.getToSoNo());//订单号码（转出）
            }

            headItems.setKDPOS(transferDtl.getFmSoLineNo());//订单行项目（转出）

//            headItems.setMAT_KDAUF(transferDtl.getToSoNo());//订单号码（转入）
            if (transferDtl.getFmSoNo() == null) {
                headItems.setMAT_KDAUF("");//订单号码（转入）
            } else {
                headItems.setMAT_KDAUF(transferDtl.getFmSoNo());//订单号码（转入）
            }
            headItems.setMAT_KDPOS(transferDtl.getToSoLineNo());//订单行项目（转入）

            headItems.setWERKS(fmFactory);//工厂（转出）
            headItems.setUMLGO(fmCodeMapping.getMappingCode());//库位（转出）/SAP说传他们的仓库


            headItems.setUMWRK(toFactory);//工厂（转入）
            headItems.setLGORT(toCodeMapping.getMappingCode());//库位（转入）/SAP说传他们的仓库

            Sku sku = skuService.getSkuByPk(goods.getSkuId());
            headItems.setMATNR(sku.getSkuCode());//物料号

//            headItems.setMENGE(goods.getQty().toString());//数量
            headItems.setMENGE(qty.toString());//数量

            headItems.setBUDAT(getDateStr());//过帐日期

            ZDT_Reserve zdt_reserve = new ZDT_Reserve();
            zdt_reserve.setRsv1("");
            zdt_reserve.setRsv2("");
            zdt_reserve.setRsv3("");
            zdt_reserve.setRsv4("");
            zdt_reserve.setRsv5("");

            headItems.setRSV(zdt_reserve);

            items.add(headItems);
        }
    }

    /**
     * 格式化日期，8位
     *
     * @param
     * @return
     */
    public String getDateStr() {

        Date now = new Date();

        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String dateStr = formatter.format(now);
        return dateStr;
    }


    /**
     * 获得当前时间时分秒
     *
     * @return
     */
    private String getTimeStr() {
        Date now = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("HHmmss");
        String timeStr = formatter.format(now);
        return timeStr;
    }



}
